package com.etoonet.android.updater;

import android.content.Context;
import android.net.Uri;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import java.io.File;

public class UpdaterConfig {
    @NonNull
    private Context context;
    private boolean showLog;
    @Nullable
    private String title;
    @Nullable
    private String description;
    @Nullable
    private String fileUrl;
    @Nullable
    private String fileName;

    private Uri destinationUri;

    private boolean isShowDownloadUI;
    private int notificationVisibility;
    private boolean isCanMediaScanner;
    private boolean isAllowedOverRoaming;
    private int allowedNetworkTypes;

    @NonNull
    public Context getContext() {
        return this.context;
    }

    public void setContext(@NonNull Context context) {
        this.context = context;
    }

    public boolean getShowLog() {
        return this.showLog;
    }

    public void setShowLog(boolean var1) {
        this.showLog = var1;
    }

    @Nullable
    public String getTitle() {
        return this.title;
    }

    public void setTitle(@Nullable String var1) {
        this.title = var1;
    }

    @Nullable
    public String getDescription() {
        return this.description;
    }

    public void setDescription(@Nullable String var1) {
        this.description = var1;
    }

    @Nullable
    public String getFileUrl() {
        return this.fileUrl;
    }

    public void setFileUrl(@Nullable String var1) {
        this.fileUrl = var1;
    }

    @Nullable
    public String getFileName() {
        return this.fileName;
    }

    public void setFileName(@Nullable String var1) {
        this.fileName = var1;
    }

    public Uri getDestinationUri() {
        return destinationUri;
    }

    public void setDestinationUri(Uri destinationUri) {
        this.destinationUri = destinationUri;
    }

    public boolean isShowDownloadUI() {
        return this.isShowDownloadUI;
    }

    public void setShowDownloadUI(boolean var1) {
        this.isShowDownloadUI = var1;
    }

    public int getNotificationVisibility() {
        return this.notificationVisibility;
    }

    public void setNotificationVisibility(int var1) {
        this.notificationVisibility = var1;
    }

    public boolean isCanMediaScanner() {
        return this.isCanMediaScanner;
    }

    public void setCanMediaScanner(boolean var1) {
        this.isCanMediaScanner = var1;
    }

    public boolean isAllowedOverRoaming() {
        return this.isAllowedOverRoaming;
    }

    public void setAllowedOverRoaming(boolean var1) {
        this.isAllowedOverRoaming = var1;
    }

    public int getAllowedNetworkTypes() {
        return this.allowedNetworkTypes;
    }

    public void setAllowedNetworkTypes(int var1) {
        this.allowedNetworkTypes = var1;
    }

    private UpdaterConfig(@NonNull Context context) {
        this.context = context.getApplicationContext();
        this.isShowDownloadUI = true;
        this.allowedNetworkTypes = ~0;
    }

    public static class Builder {
        private Context context;
        private UpdaterConfig updaterConfig;

        public Builder(@NonNull Context context) {
            super();
            this.context = context;
            this.updaterConfig = new UpdaterConfig(context.getApplicationContext());
        }

        @NonNull
        public UpdaterConfig.Builder showLog(boolean show) {
            this.updaterConfig.setShowLog(show);
            return this;
        }

        @NonNull
        public UpdaterConfig.Builder setTitle(@NonNull String title) {
            this.updaterConfig.setTitle(title);
            return this;
        }

        @NonNull
        public UpdaterConfig.Builder setDescription(@NonNull String description) {
            this.updaterConfig.setDescription(description);
            return this;
        }

        public void setDestinationInExternalFilesDir(String dirType, String subPath) {
            final File file = this.context.getExternalFilesDir(dirType);
            if (file == null) {
                throw new IllegalStateException("Failed to get external storage files directory");
            } else if (file.exists()) {
                if (!file.isDirectory()) {
                    throw new IllegalStateException(file.getAbsolutePath() +
                            " already exists and is not a directory");
                }
            } else {
                if (!file.mkdirs()) {
                    throw new IllegalStateException("Unable to create directory: "+
                            file.getAbsolutePath());
                }
            }

            this.updaterConfig.setDestinationUri(getUriFromBase(file, subPath));
        }

        public void setDestinationInExternalPublicDir(String dirType, String subPath) {
            File file = Environment.getExternalStoragePublicDirectory(dirType);
            if (file == null) {
                throw new IllegalStateException("Failed to get external storage public directory");
            } else if (file.exists()) {
                if (!file.isDirectory()) {
                    throw new IllegalStateException(file.getAbsolutePath() +
                            " already exists and is not a directory");
                }
            } else {
                if (!file.mkdirs()) {
                    throw new IllegalStateException("Unable to create directory: "+
                            file.getAbsolutePath());
                }
            }

            this.updaterConfig.setDestinationUri(getUriFromBase(file, subPath));
        }

        private Uri getUriFromBase(File base, String subPath) {
            if (subPath == null) {
                throw new NullPointerException("subPath cannot be null");
            }
            return Uri.withAppendedPath(Uri.fromFile(base), subPath);
        }

        public void setDestinationUri(Uri destinationUri) {
            this.updaterConfig.setDestinationUri(destinationUri);
        }

        @NonNull
        public UpdaterConfig.Builder setFileName(@NonNull String fileName) {
            this.updaterConfig.setFileName(fileName);
            return this;
        }

        @NonNull
        public UpdaterConfig.Builder setFileUrl(@NonNull String url) {
            this.updaterConfig.setFileUrl(url);
            return this;
        }

        @NonNull
        public UpdaterConfig.Builder setIsShowDownloadUI(boolean isShowDownloadUI) {
            this.updaterConfig.setShowDownloadUI(isShowDownloadUI);
            return this;
        }

        @NonNull
        public UpdaterConfig.Builder setNotificationVisibility(int notificationVisibility) {
            this.updaterConfig.setNotificationVisibility(notificationVisibility);
            return this;
        }

        @NonNull
        public UpdaterConfig.Builder setCanMediaScanner(boolean canMediaScanner) {
            this.updaterConfig.setCanMediaScanner(canMediaScanner);
            return this;
        }

        @NonNull
        public UpdaterConfig.Builder setAllowedOverRoaming(boolean allowedOverRoaming) {
            this.updaterConfig.setAllowedOverRoaming(allowedOverRoaming);
            return this;
        }

        @NonNull
        public UpdaterConfig.Builder setContext(@NonNull Context context) {
            this.updaterConfig.setContext(context);
            return this;
        }

        @NonNull
        public UpdaterConfig.Builder setAllowedNetworkTypes(int allowedNetworkTypes) {
            this.updaterConfig.setAllowedNetworkTypes(allowedNetworkTypes);
            return this;
        }

        @NonNull
        public UpdaterConfig build() {
            return this.updaterConfig;
        }
    }

    public interface AllowedNetworkType {
        int NETWORK_MOBILE = 1;
        int NETWORK_WIFI = 2;
    }

    @NonNull
    public static UpdaterConfig defaultConfig(@NonNull Context context, @Nullable String title, @Nullable String desc) {
        String notificationTitle = title;
        if (title == null) {
            notificationTitle = context.getString(R.string.system_download_title);
        }

        String notificationDesc = desc;
        if (desc == null) {
            notificationDesc = context.getString(R.string.system_download_description);
        }
        UpdaterConfig.Builder builder = new UpdaterConfig.Builder(context);
        builder.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "update.apk");
        builder = builder.setTitle(notificationTitle);
        return builder.setDescription(notificationDesc).setCanMediaScanner(true).setNotificationVisibility(0).setIsShowDownloadUI(true).showLog(true).build();
    }

    @NonNull
    public static UpdaterConfig defaultConfig(@NonNull Context context) {
        return defaultConfig(context, null, null);
    }


}
